<?php

namespace Emergine\Libs
{
/**
   * lib.models -- Emergine Models Library
   * @version: 1.0
   * @author: Hleb Piatrou <h.piatrou@softteco.com>
   * @link: http://code.google.com/p/emergine/
   * @copyright: Copyright 2011-2012 Hleb Piatrou
   * @license: MIT License http://www.opensource.org/licenses/mit-license.php
   * @interface: Common Model Interface (CMI)
   */
   
/**
   * Additional libs inclusion
   * @CMI: Common Model Interface
   * @lib.spyc: Emergine YAML Library
   * @lib.settings: Emergine Settings Library
   */

	include_once "./interfaces/CMI.php";
	include_once "./libraries/lib.spyc.php";
	include_once "./libraries/lib.settings.php";

/* Using additional namespaces */
    
	use Emergine\Interfaces\Models as ModelsInterface;	

/**
   * Emergine Models class
   * 
   * This class can be used to manage the object-related models, 
   * using special functions, which was builded by the AR pattern.
   * 
   * Example of usage:
   * <code>
   * Models::SQLAll(); // Get the ALTER/CREATE TABLE construction
   * Models::SyncDB(); // Syncronize your models with database
   * </code>
   * @interface: Models
   */
   	
	class Models implements ModelsInterface
    {
		private $field;
		public $table;
		
		public function __construct($model)
		{
			$object = Spyc::YAMLLoad(Settings::Files("models"));	
			$table = array_keys(Models::ArrayContent());		
			$this->field = $object[$model];
			$this->table = $model;
			return $this->field;
		}
		/**
		 * @access: public
		 * @param: none
		 * @return: array
		 */
		public function ArrayContent()
		{
			$object = Spyc::YAMLLoad(Settings::Files("models"));
			return (array)$object;
		}
		/**
		 * @access: public
		 * @param: none
		 * @return: object
		 */		
		public function ObjectContent()
		{
			$object = Spyc::YAMLLoad(Settings::Files("models"));
			return (object)$object;
		}
		/**
		 * @access: public
		 * @param: int $index - The index number of models array
		 * @return: string
		 */		
		public function TableName($index)
		{
			$table = array_keys(Models::ArrayContent());
			if (isset($table[$index])) 
			{ 
				return $table[$index]; 
			}
			else return "WARNING";
		}
		/**
		 * @access: public
		 * @param: int $index - The index number of models array
		 * @return: array
		 */		
		public function TableContent($index)
		{
			$table = array_keys(Models::ArrayContent());
			$table_content = (array)Models::ObjectContent()->{$table[$index]};
			unset($table_content["options"]);
			return $table_content;
		}
		/**
		 * @access: public
		 * @param: string $option_name - the name of table option
		 * @return: string
		 */
		public function TableOptions($option_name)
		{
			$table = array_keys(Models::ArrayContent());
			$table_content = (array)Models::ObjectContent()->{$table[$index]};
			$options = $table_content["options"][$option_name];
			return $options;
		}
		/**
		 * @access: public
		 * @param: int $table_undex - the number of table, int $index - the number of field
		 * @return: string
		 */		
		public function Field($table_index, $index)
		{
			$table = array_keys(Models::TableContent($table_index));
			$field = $table[$index];
			return $field;
		}
		/**
		 * @access: public
		 * @param: int $table_undex - the number of table, int $index - the number of field
		 * @return: string
		 */			
		public function FieldType($table_index, $index)
		{
			$table = array_values(Models::TableContent($table_index));
			$field_type = $table[$index]["field_type"];
			return $field_type;
		}
		/**
		 * @access: public
		 * @param: @int $table_undex - the number of table, @int $index - the number of field
		 * @return: int
		 */		
		public function MaxValue($table_index, $index)
		{
			$table = array_values(Models::TableContent($table_index));
			$max_value = $table[$index]["max_value"];
			return $max_value;
		}
		/**
		 * @access: public
		 * @param: @string $query - SQL construction, which you want to generate
		 * @ from your models. Supported queries: AlterTable, CreateTable
		 * @return: none
		 */
		public function DBServer($query, $param)
		{
			$datasource = (string)Settings::DBOptions("datasource");
			include_once "./libraries/lib.".$datasource.".php";
			$result = call_user_func(array($datasource, $query), $param);
			return $result;
		}
		/**
		 * @access: public
		 * @param: none
		 * @return: none
		 */		
		public function SyncDB()
		{
			Models::DBServer("SyncDB", '');
		}
		/**
		 * @access: public
		 * @param: none
		 * @return: none
		 */		
		public function SQLAll()
		{
			return Models::DBServer("CreateTable", '');
		}
		/**
		 * @access: public
		 * @param: object $object - an object of inserted keys and values
		 * @return: array
		 */	
		public function Save($object)
		{
			$selected_table = $object->table;
			$field_properties = $object->field; 
			unset($object->field);
			unset($field_properties['options']);
			$required_keys = array_keys($field_properties);
			$inserted_keys = array_keys((array)$object);
			$inserted_values = array_values((array)$object);
			for ($i=0; $i<count($required_keys); $i++)
			{
				for ($j=0; $j<count($inserted_keys); $j++)
				{
					if ($required_keys[$i] == $inserted_keys[$j])
					{
						$result_object[$inserted_keys[$j]] = $inserted_values[$j];
					}
				}
			}
			$result_object['table'] = $selected_table;
			$query = Models::DBServer("Insert", (object)$result_object);
			return $result_object;
		}
		/**
		 * @access: public
		 * @param: object $object - an object of inserted keys and values
		 * @return: array
		 */	
		 public function GetObjects($table)
		 {
			Models::DBServer("Select", $table);
		 }
		
	}
}
?>
